import socket
import argparse


def create_magic_packet(mac_address):
    # 清理MAC地址格式（支持'-'、':'或空格分隔）
    mac = mac_address.strip().replace('-', '').replace(':', '').replace(' ', '')
    if len(mac) != 12:
        raise ValueError("Invalid MAC address format")

    # 将MAC地址转换为字节
    mac_bytes = bytes.fromhex(mac)

    # 构建魔术包：6字节0xFF + 16次重复MAC地址
    magic_packet = b'\xff' * 6 + mac_bytes * 16
    return magic_packet


def send_wol(mac_address, broadcast_ip='255.255.255.255', port=9):
    packet = create_magic_packet(mac_address)
    print(packet)
    # 创建UDP Socket并发送广播
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        sock.sendto(packet, (broadcast_ip, port))
    print(f"魔术包已发送至 {mac_address}")


import socket
import json
import threading
import logging
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
from tkinter import *
from tkinter import ttk, messagebox, filedialog

# -------------------- 配置管理模块 --------------------
DEFAULT_CONFIG = {
    "udp_ip": "0.0.0.0",
    "udp_port": 9,
    "http_ip": "0.0.0.0",
    "http_port": 8000,
    "send_protocol": "UDP",
    "send_ip": "127.0.0.1",
    "send_port": 9999
}


class ConfigManager:
    def __init__(self, filename='config.json'):
        self.filename = filename
        self.config = DEFAULT_CONFIG.copy()
        self.load_config()

    def load_config(self):
        try:
            with open(self.filename, 'r') as f:
                self.config.update(json.load(f))
        except FileNotFoundError:
            self.save_config()

    def save_config(self):
        with open(self.filename, 'w') as f:
            json.dump(self.config, f, indent=2)


# -------------------- 网络服务模块 --------------------
class UDPServer:
    def __init__(self, ip, port, log_callback):
        self.ip = ip
        self.port = port
        self.log = log_callback
        self.running = False

    def start(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((self.ip, self.port))
        self.running = True
        self.thread = threading.Thread(target=self._listen)
        self.thread.start()

    def _listen(self):
        while self.running:
            try:
                data, addr = self.sock.recvfrom(1024)
                self.log(f"UDP [{addr[0]}:{addr[1]}] -> {data.decode()}")
                self.sock.sendto(f"ACK {len(data)}B".encode(), addr)
            except Exception as e:
                if self.running:
                    self.log(f"UDP错误: {str(e)}", level="ERROR")

    def stop(self):
        self.running = False
        if hasattr(self, 'sock'):
            self.sock.close()


class HTTPHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/plain')
        self.end_headers()
        self.wfile.write(f"GET路径: {self.path}\n".encode())

    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        self.send_response(200)
        self.send_header('Content-type', 'text/plain')
        self.end_headers()
        self.wfile.write(f"POST数据: {post_data.decode()}\n".encode())


class HTTPServerWrapper:
    def __init__(self, ip, port, log_callback):
        self.server = ThreadingHTTPServer((ip, port), HTTPHandler)
        self.log = log_callback
        self.running = False

    def start(self):
        self.running = True
        self.thread = threading.Thread(target=self.server.serve_forever)
        self.thread.start()

    def stop(self):
        self.server.shutdown()
        self.running = False


# -------------------- GUI界面模块 --------------------
class NetworkDebuggerGUI:
    def __init__(self, config):
        self.config = config
        self.root = Tk()
        self.root.title("网络调试工具 v1.0")

        # 服务控制区
        self.setup_service_controls()
        # 发送测试区
        self.setup_send_controls()
        # 日志显示区
        self.setup_log_viewer()
        # 状态栏
        self.setup_status_bar()

        self.udp_server = None
        self.http_server = None

    def setup_service_controls(self):
        frame = LabelFrame(self.root, text="服务配置")
        frame.grid(row=0, column=0, padx=10, pady=5, sticky="ew")

        # UDP配置
        Label(frame, text="UDP监听IP:").grid(row=0, column=0)
        self.udp_ip_entry = Entry(frame)
        self.udp_ip_entry.insert(0, self.config.config['udp_ip'])
        self.udp_ip_entry.grid(row=0, column=1)

        Label(frame, text="端口:").grid(row=0, column=2)
        self.udp_port_entry = Entry(frame, width=6)
        self.udp_port_entry.insert(0, self.config.config['udp_port'])
        self.udp_port_entry.grid(row=0, column=3)

        # HTTP配置
        Label(frame, text="HTTP监听IP:").grid(row=1, column=0)
        self.http_ip_entry = Entry(frame)
        self.http_ip_entry.insert(0, self.config.config['http_ip'])
        self.http_ip_entry.grid(row=1, column=1)

        Label(frame, text="端口:").grid(row=1, column=2)
        self.http_port_entry = Entry(frame, width=6)
        self.http_port_entry.insert(0, self.config.config['http_port'])
        self.http_port_entry.grid(row=1, column=3)

        # 控制按钮
        self.start_btn = Button(frame, text="启动服务", command=self.toggle_services)
        self.start_btn.grid(row=0, column=4, rowspan=2, padx=10)

    def setup_send_controls(self):
        frame = LabelFrame(self.root, text="发送测试")
        frame.grid(row=1, column=0, padx=10, pady=5, sticky="ew")

        # 协议选择
        Label(frame, text="协议:").grid(row=0, column=0)
        self.protocol_var = StringVar(value=self.config.config['send_protocol'])
        protocols = ['UDP', 'HTTP GET', 'HTTP POST']
        OptionMenu(frame, self.protocol_var, *protocols).grid(row=0, column=1)

        # 目标配置
        Label(frame, text="目标IP:").grid(row=0, column=2)
        self.target_ip_entry = Entry(frame)
        self.target_ip_entry.insert(0, self.config.config['send_ip'])
        self.target_ip_entry.grid(row=0, column=3)

        Label(frame, text="端口:").grid(row=0, column=4)
        self.target_port_entry = Entry(frame, width=6)
        self.target_port_entry.insert(0, self.config.config['send_port'])
        self.target_port_entry.grid(row=0, column=5)

        # 发送内容
        self.send_text = Text(frame, height=4, width=50)
        self.send_text.grid(row=1, column=0, columnspan=6, pady=5)

        # 发送按钮
        Button(frame, text="发送", command=self.send_test).grid(row=2, column=5)

    def setup_log_viewer(self):
        frame = LabelFrame(self.root, text="日志监控")
        frame.grid(row=2, column=0, padx=10, pady=5, sticky="nsew")

        self.log_text = Text(frame, wrap=WORD, state=DISABLED)
        scrollbar = Scrollbar(frame, command=self.log_text.yview)
        self.log_text.configure(yscrollcommand=scrollbar.set)

        self.log_text.pack(side=LEFT, fill=BOTH, expand=True)
        scrollbar.pack(side=RIGHT, fill=Y)

    def setup_status_bar(self):
        self.status_var = StringVar()
        status_bar = Label(self.root, textvariable=self.status_var, bd=1, relief=SUNKEN, anchor=W)
        status_bar.grid(row=3, column=0, sticky="ew")

    def log_message(self, message, level="INFO"):
        self.log_text.configure(state=NORMAL)
        self.log_text.insert(END, f"[{level}] {message}\n")
        self.log_text.see(END)
        self.log_text.configure(state=DISABLED)

    def toggle_services(self):
        if self.start_btn['text'] == "启动服务":
            try:
                # 保存配置
                self.save_config()
                # 启动UDP
                self.udp_server = UDPServer(
                    self.config.config['udp_ip'],
                    self.config.config['udp_port'],
                    self.log_message
                )
                self.udp_server.start()
                # 启动HTTP
                self.http_server = HTTPServerWrapper(
                    self.config.config['http_ip'],
                    self.config.config['http_port'],
                    self.log_message
                )
                self.http_server.start()
                self.start_btn.config(text="停止服务")
                self.status_var.set("服务运行中...")
            except Exception as e:
                messagebox.showerror("启动失败", str(e))
        else:
            self.udp_server.stop()
            self.http_server.stop()
            self.start_btn.config(text="启动服务")
            self.status_var.set("服务已停止")

    def send_test(self):
        protocol = self.protocol_var.get()
        ip = self.target_ip_entry.get()
        port = int(self.target_port_entry.get())
        data = self.send_text.get("1.0", END).strip()

        try:
            if protocol == "UDP":
                with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
                    sock.sendto(data.encode(), (ip, port))
                    response, _ = sock.recvfrom(1024)
                    self.log_message(f"UDP响应: {response.decode()}")
            elif "HTTP" in protocol:
                import requests
                url = f"http://{ip}:{port}"
                if protocol == "HTTP GET":
                    response = requests.get(url + data)
                else:
                    response = requests.post(url, data=data)
                self.log_message(f"HTTP响应 [{response.status_code}]: {response.text}")
        except Exception as e:
            self.log_message(f"发送失败: {str(e)}", "ERROR")

    def save_config(self):
        self.config.config.update({
            'udp_ip': self.udp_ip_entry.get(),
            'udp_port': int(self.udp_port_entry.get()),
            'http_ip': self.http_ip_entry.get(),
            'http_port': int(self.http_port_entry.get()),
            'send_protocol': self.protocol_var.get(),
            'send_ip': self.target_ip_entry.get(),
            'send_port': int(self.target_port_entry.get())
        })
        self.config.save_config()


if __name__ == "__main__":
    config = ConfigManager()
    gui = NetworkDebuggerGUI(config)
    gui.root.mainloop()

if __name__ == "__main__":
    # 命令行参数解析
    # parser = argparse.ArgumentParser(description="发送Wake-on-LAN魔术包")
    # parser.add_argument('mac', help='目标设备的MAC地址（例如：60-45-2E-FD-BF-A1）')
    # args = parser.parse_args()

    try:
        send_wol("60-45-2E-FD-BF-A1")
    except Exception as e:
        print(f"错误: {str(e)}")
